<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>jsonp跨域请求 | Jason&#39;s Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="jsonp跨域请求">
<meta property="og:type" content="article">
<meta property="og:title" content="jsonp跨域请求">
<meta property="og:url" content="https://xianguoji.gitee.io/myblog/2017/03/12/2017-03-12-jsonp%E8%B7%A8%E5%9F%9F/index.html">
<meta property="og:site_name" content="Jason&#39;s Blog">
<meta property="og:description" content="jsonp跨域请求">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2017-03-11T16:00:00.000Z">
<meta property="article:modified_time" content="2020-08-12T06:46:10.812Z">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="跨域请求">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/myblog/" title="Jason&#39;s Blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/myblog/css/style.css">

<meta name="generator" content="Hexo 5.0.2"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/myblog/" id="logo">人与人的悲欢并不相通，孤独是生命的本质。</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/myblog/" id="subtitle">欢迎来到我的个人网站</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/myblog/">Home</a>
        
          <a class="main-nav-link" href="/myblog/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/myblog/" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://xianguoji.gitee.io/myblog"></form>
      </div>
    </div>
  </div>
</header>
<style>
  #logo{
    text-shadow:0 0 5px #000;
    /* font-weight: bold; */
  }
  #subtitle-wrap{
    margin-top: 50px;
  }
</style>
      <div class="outer">
        <section id="main"><article id="post-2017-03-12-jsonp跨域" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/myblog/2017/03/12/2017-03-12-jsonp%E8%B7%A8%E5%9F%9F/" class="article-date">
  <time datetime="2017-03-11T16:00:00.000Z" itemprop="datePublished">2017-03-12</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      jsonp跨域请求
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p> 跨域一词从字面意思看，就是跨域名嘛，但实际上跨域的范围绝对不止那么狭隘。具体概念如下：只要协议、域名、端口有任何一个不同，都被当作是不同的域。之所以会产生跨域这个问题呢，其实也很容易想明白，要是随便引用外部文件，不同标签下的页面引用类似的彼此的文件，浏览器很容易懵逼的，安全也得不到保障了就。什么事，都是安全第一嘛。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。所以我们要通过一些方法使本域的js能够操作其他域的页面对象或者使其他域的js能操作本域的页面对象（iframe之间）。下面是具体的跨域情况详解：</p>
<p>URL                           说明                    是否允许通信</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/a.js">http://www.a.com/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/b.js">http://www.a.com/b.js</a>         同一域名下               允许</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/lab/a.js">http://www.a.com/lab/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/script/b.js">http://www.a.com/script/b.js</a>  同一域名下不同文件夹      允许</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com:8000/a.js">http://www.a.com:8000/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/b.js">http://www.a.com/b.js</a>         同一域名，不同端口        不允许</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/a.js">http://www.a.com/a.js</a></p>
<p><a target="_blank" rel="noopener" href="https://www.a.com/b.js">https://www.a.com/b.js</a>        同一域名，不同协议        不允许</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/a.js">http://www.a.com/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://70.32.92.74/b.js">http://70.32.92.74/b.js</a>       域名和域名对应ip         不允许</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/a.js">http://www.a.com/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://script.a.com/b.js">http://script.a.com/b.js</a>      主域相同，子域不同        不允许（cookie这种情况下也不允许访问）</p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/a.js">http://www.a.com/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://a.com/b.js">http://a.com/b.js</a>             同一域名，不同二级域名（同上） 不允许（cookie这种情况下也不允许访问）</p>
<p><a target="_blank" rel="noopener" href="http://www.cnblogs.com/a.js">http://www.cnblogs.com/a.js</a></p>
<p><a target="_blank" rel="noopener" href="http://www.a.com/b.js">http://www.a.com/b.js</a>         不同域名                  不允许</p>
<h3 id="跨域请求有6种"><a href="#跨域请求有6种" class="headerlink" title="跨域请求有6种"></a>跨域请求有6种</h3><p>1.通过document.domain跨域</p>
<p>2.通过location.hash跨域</p>
<p>3.通过HTML5的postMessage方法跨域</p>
<p>4.通过jsonp跨域</p>
<p>5.通过CORS跨域</p>
<p>6.通过window.name跨域</p>
<h4 id="我们详细说第4，5种，jsonp跨域和CORS跨域。"><a href="#我们详细说第4，5种，jsonp跨域和CORS跨域。" class="headerlink" title="我们详细说第4，5种，jsonp跨域和CORS跨域。"></a>我们详细说第4，5种，jsonp跨域和CORS跨域。</h4><h3 id="通过jsonp跨域"><a href="#通过jsonp跨域" class="headerlink" title="通过jsonp跨域"></a>通过jsonp跨域</h3><p>这几种都是双向通信的，即两个iframe，页面与iframe或是页面与页面之间的，下面说几种单项跨域的（一般用来获取数据），因为通过script标签引入的js是不受同源策略的限制的。所以我们可以通过script标签引入一个js或者是一个其他后缀形式（如php，jsp等）的文件，此文件返回一个js函数的调用。</p>
<p>比如，有个a.html页面，它里面的代码需要利用ajax获取一个不同域上的json数据，假设这个json数据地址是<a target="_blank" rel="noopener" href="http://damonare.cn/data.php,%E9%82%A3%E4%B9%88a.html%E4%B8%AD%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%B1%E5%8F%AF%E4%BB%A5%E8%BF%99%E6%A0%B7%EF%BC%9A">http://damonare.cn/data.php,那么a.html中的代码就可以这样：</a></p>
<pre><code>&lt;script type=&quot;text/javascript&quot;&gt;
    function dosomething(jsondata)&#123;
        //处理获得的json数据
    &#125;
&lt;/script&gt;
&lt;script src=&quot;http://example.com/data.php?callback=dosomething&quot;&gt;&lt;/script&gt;</code></pre>
<p>我们看到获取数据的地址后面还有一个callback参数，按惯例是用这个参数名，但是你用其他的也一样。当然如果获取数据的jsonp地址页面不是你自己能控制的，就得按照提供数据的那一方的规定格式来操作了。</p>
<p>因为是当做一个js文件来引入的，所以<a target="_blank" rel="noopener" href="http://damonare.cn/data.php%E8%BF%94%E5%9B%9E%E7%9A%84%E5%BF%85%E9%A1%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E8%83%BD%E6%89%A7%E8%A1%8C%E7%9A%84js%E6%96%87%E4%BB%B6%EF%BC%8C%E6%89%80%E4%BB%A5%E8%BF%99%E4%B8%AA%E9%A1%B5%E9%9D%A2%E7%9A%84php%E4%BB%A3%E7%A0%81%E5%8F%AF%E8%83%BD%E6%98%AF%E8%BF%99%E6%A0%B7%E7%9A%84(%E4%B8%80%E5%AE%9A%E8%A6%81%E5%92%8C%E5%90%8E%E7%AB%AF%E7%BA%A6%E5%AE%9A%E5%A5%BD%E5%93%A6)">http://damonare.cn/data.php返回的必须是一个能执行的js文件，所以这个页面的php代码可能是这样的(一定要和后端约定好哦)</a>:</p>
<pre><code>&lt;?php
$callback = $_GET[&#39;callback&#39;];//得到回调函数名
$data = array(&#39;a&#39;,&#39;b&#39;,&#39;c&#39;);//要返回的数据
echo $callback.&#39;(&#39;.json_encode($data).&#39;)&#39;;//输出
?&gt;</code></pre>
<p>最终，输出结果为：</p>
<pre><code>dosomething([‘a’,’b’,’c’]);</code></pre>
<p>如果你的页面使用jquery，那么通过它封装的方法就能很方便的来进行jsonp操作了。</p>
   <script type="text/javascript">
       $.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){
           //处理获得的json数据
       });
   </script>

<p>jquery会自动生成一个全局函数来替换callback=?中的问号，之后获取到数据后又会自动销毁，实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域，不跨域的话，就调用普通的ajax方法；跨域的话，则会以异步加载js文件的形式来调用jsonp的回调函数。</p>
<h3 id="JSONP的优缺点"><a href="#JSONP的优缺点" class="headerlink" title="JSONP的优缺点"></a>JSONP的优缺点</h3><p>JSONP的优点是：它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制；它的兼容性更好，在更加古老的浏览器中都可以运行，不需要XMLHttpRequest或ActiveX的支持；并且在请求完毕后可以通过调用callback的方式回传结果。</p>
<p>JSONP的缺点则是：它只支持GET请求而不支持POST等其它类型的HTTP请求；它只支持跨域HTTP请求这种情况，不能解决不同域的两个页面之间如何进行JavaScript调用的问题。</p>
<h3 id="CORS跨域"><a href="#CORS跨域" class="headerlink" title="CORS跨域"></a>CORS跨域</h3><p>CORS（Cross-Origin Resource Sharing）跨域资源共享，定义了必须在访问跨域资源时，浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通，从而决定请求或响应是应该成功还是失败。目前，所有浏览器都支持该功能，IE浏览器不能低于IE10。整个CORS通信过程，都是浏览器自动完成，不需要用户参与。对于开发者来说，CORS通信与同源的AJAX通信没有差别，代码完全一样。浏览器一旦发现AJAX请求跨源，就会自动添加一些附加的头信息，有时还会多出一次附加的请求，但用户不会有感觉。</p>
<p>因此，实现CORS通信的关键是服务器。只要服务器实现了CORS接口，就可以跨源通信。</p>
<p>平时的ajax请求可能是这样的:</p>
<pre><code>&lt;script type=&quot;text/javascript&quot;&gt;
    var xhr = new XMLHttpRequest();
    xhr.open(&quot;POST&quot;, &quot;/damonare&quot;,true);
    xhr.send();
&lt;/script&gt;</code></pre>
<p>以上damonare部分是相对路径，如果我们要使用CORS，相关Ajax代码可能如下所示：</p>
<pre><code>&lt;script type=&quot;text/javascript&quot;&gt;
    var xhr = new XMLHttpRequest();
    xhr.open(&quot;￼GET&quot;, &quot;http://segmentfault.com/u/trigkit4/&quot;,true);
    xhr.send();
&lt;/script&gt;</code></pre>
<p>代码与之前的区别就在于相对路径换成了其他域的绝对路径，也就是你要跨域访问的接口地址。</p>
<p>服务器端对于CORS的支持，主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置，就可以允许Ajax进行跨域的访问。关于CORS更多了解可以看下阮一峰老师的这一篇文章：<a target="_blank" rel="noopener" href="http://www.ruanyifeng.com/blog/2016/04/cors.html">跨域资源共享 CORS 详解</a></p>
<h4 id="CORS和JSONP对比"><a href="#CORS和JSONP对比" class="headerlink" title="CORS和JSONP对比"></a>CORS和JSONP对比</h4><p>JSONP只能实现GET请求，而CORS支持所有类型的HTTP请求。</p>
<p>使用CORS，开发者可以使用普通的XMLHttpRequest发起请求和获得数据，比起JSONP有更好的错误处理。</p>
<p>JSONP主要被老的浏览器支持，它们往往不支持CORS，而绝大多数现代浏览器都已经支持了CORS）。</p>
<p>CORS与JSONP相比，无疑更为先进、方便和可靠。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://xianguoji.gitee.io/myblog/2017/03/12/2017-03-12-jsonp%E8%B7%A8%E5%9F%9F/" data-id="ckds6fxa7000fk8qc94uvhep8" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/myblog/tags/%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82/" rel="tag">跨域请求</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/myblog/2017/03/12/2017-03-12-Rem%E8%87%AA%E9%80%82%E5%BA%94js-%E4%BC%98%E5%8C%96flexible.js/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          Rem自适应js-优化flexible.js
        
      </div>
    </a>
  
  
    <a href="/myblog/2017/02/23/2017-02-23-%E7%BD%91%E7%AB%99%E4%B8%8A%E5%AE%9E%E7%8E%B0qq%E8%81%8A%E5%A4%A9%EF%BC%8C%E7%BD%91%E7%AB%99%E7%BB%91%E5%AE%9A%E5%BE%AE%E4%BF%A1%E7%99%BB%E5%BD%95/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">网站上实现qq聊天，网站绑定微信登录</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/javascript/" rel="tag">javascript</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/js/" rel="tag">js</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/rem/" rel="tag">rem</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/%E5%85%B6%E4%BB%96/" rel="tag">其他</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/%E5%8D%9A%E5%AE%A2/" rel="tag">博客</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" rel="tag">性能优化</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/%E6%A1%86%E6%9E%B6/" rel="tag">框架</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/%E7%A7%BB%E5%8A%A8%E7%AB%AF/" rel="tag">移动端</a></li><li class="tag-list-item"><a class="tag-list-link" href="/myblog/tags/%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82/" rel="tag">跨域请求</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/myblog/tags/javascript/" style="font-size: 20px;">javascript</a> <a href="/myblog/tags/js/" style="font-size: 10px;">js</a> <a href="/myblog/tags/rem/" style="font-size: 16.67px;">rem</a> <a href="/myblog/tags/%E5%85%B6%E4%BB%96/" style="font-size: 10px;">其他</a> <a href="/myblog/tags/%E5%8D%9A%E5%AE%A2/" style="font-size: 13.33px;">博客</a> <a href="/myblog/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" style="font-size: 13.33px;">性能优化</a> <a href="/myblog/tags/%E6%A1%86%E6%9E%B6/" style="font-size: 10px;">框架</a> <a href="/myblog/tags/%E7%A7%BB%E5%8A%A8%E7%AB%AF/" style="font-size: 13.33px;">移动端</a> <a href="/myblog/tags/%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82/" style="font-size: 10px;">跨域请求</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2020/08/">August 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2017/06/">June 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2017/05/">May 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2017/04/">April 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2017/03/">March 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2017/02/">February 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2017/01/">January 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2016/10/">October 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2016/09/">September 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2016/08/">August 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2015/08/">August 2015</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/myblog/2020/08/13/2020-08-13%E4%B8%AA%E4%BA%BA%E7%AE%80%E5%8E%86/">(no title)</a>
          </li>
        
          <li>
            <a href="/myblog/2017/06/18/2017-06-18-%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E4%B8%80/">前端性能优化一</a>
          </li>
        
          <li>
            <a href="/myblog/2017/05/15/2017-05-15-%E8%B0%83%E7%94%A8%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE%E6%8F%92%E4%BB%B6-%E6%9B%B4%E6%96%B0/">调用百度地图插件-更新</a>
          </li>
        
          <li>
            <a href="/myblog/2017/04/23/2017-04-23-vue%E6%90%AD%E5%BB%BA%E9%A1%B9%E7%9B%AE/">vue搭建项目</a>
          </li>
        
          <li>
            <a href="/myblog/2017/04/21/2017-04-21-%E8%B0%83%E7%94%A8%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE%E6%8F%92%E4%BB%B6/">调用百度地图插件</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2020 Jason<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/myblog/" class="mobile-nav-link">Home</a>
  
    <a href="/myblog/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/myblog/fancybox/jquery.fancybox.css">

  
<script src="/myblog/fancybox/jquery.fancybox.pack.js"></script>




<script src="/myblog/js/script.js"></script>




  </div>
</body>
</html>